// -*- mode: c++ -*-
%define DOCSTRING
"Python bindings for Cosmic String Simulations"
%enddef

%module(docstring=DOCSTRING) CSL

 %{
#define SWIG_FILE_WITH_INIT
#include "../OutputFile.hpp"
#include "../csNode.hpp"
#include "../FriedmannEvolution.hpp"
#include "../evolutionSP.hpp"
#include "../latticeSP.hpp"    
#include "../mt64.h"
#include "../densitySP.hpp"
%}

%include cpointer.i
%include std_list.i
// %include numpy.i

%template(SList) std::list<csSegment*>;

%init
%{
//    import_array();
%}
class OutputFile {
public:
    OutputFile(char *filename);
    virtual ~OutputFile();
    FILE *file();
};

class InputFile {
public:
    InputFile(char *filename);
    virtual ~InputFile();
    FILE *file();
};

class csSegment {
public:
    inline csNode* node1();
    inline csNode* node2();
    static csSegment *connect(csNode* n1, csNode* n2);
    static SegmentList connections(csNode* n1, csNode* n2);
};

class csNode {
public:
    csNode();
    csNode(const csNode& orig);
    virtual ~csNode();
    csSegment* connection(const int i);
    csNode* connected_node(const int i);
    int connections();
    //friend csSegment *csSegment::connect(csNode* n1, csNode* n2);
    //friend SegmentList csSegment::connections(csNode* n1, csNode* n2);
};


class FriedmannEvolution {
public:
    FriedmannEvolution(double OmegaRadiation, double OmegaMatter, double a0, double H0);
    FriedmannEvolution(const FriedmannEvolution& orig);
    virtual ~FriedmannEvolution();
    void step(double deta);
    double get_OmegaRadiation();
    double get_OmegaMatter();
    double get_OmegaVacuum();
    double get_scale_parameter();
    double get_H();
    double get_eta();
    void set_eta(double eta);
    void save(FILE * filename);
    void load(FILE * filename);
};
class latticeSP {
public:

    latticeSP(int nx, int ny, int nz, int n);
    latticeSP(const latticeSP& orig);
    virtual ~latticeSP();
    void init_random(double sigmaPI);
    int save_vtk(const char *filename);
    void save_strings_vtk(const char* filename);    
    nodeSP *first_node() {return mNodes;};    
    int get_lattice_size() {return mNx*mNy*mNz;};
    int get_N() {return mN;};
    void save(FILE * filename);
    void load(FILE * filename);
};

class Box {
public:
    Box(int xmin, int xmax, int ymin, int ymax, int zmin, int zmax);
    int xmin();
    int ymin();
    int zmin();
    int xmax();
    int ymax();
    int zmax();
};

class evolutionSP {
public:
  evolutionSP(double dh, double dt);
  evolutionSP(const evolutionSP& orig);
  evolutionSP(double dh,
			  double dt,
			  int    lsizex,
			  int    lsizey,
			  int    lsizez,
			  int    nx,
			  int    ny,
			  int    nz);


  virtual ~evolutionSP();
  void operator()(latticeSP* src, latticeSP* dst, FriedmannEvolution* frw);
  double deltaT();
  double deltaH();
  void set_dt(double dt);
};



class densitySP {
public:
    densitySP(int    lsizex,
                int    lsizey,
                int    lsizez,
                int    nx,
                int    ny,
                int    nz);
    virtual ~densitySP();
    void operator()(latticeSP& l);
    double color_density(int n);
    double total_density();
};    

/* initializes mt[NN] with a seed */
void init_genrand64(unsigned long long seed);

